package com.fingard.dsp.bank.directbank.citic04;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.FailCode;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.ISinglePay;
import com.fingard.dsp.bank.reqrespobj.single.*;
import com.fingard.dsp.bank.reqrespobj.single.detail.RetAtsSglDetail;
import com.fingard.text.StringHelper;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import java.util.Date;

public class CITIC04SinglePay extends CITIC04Base implements ISinglePay {

    public RetAtsSingle d_1908_SglPay(ReqSingle p_req1908) throws Exception {
        RetAtsSingle retAts = new RetAtsSingle(p_req1908.reqHeader);
        RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail(p_req1908);
        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_req1908.singleDetail.payAct, "");
            if (actItem == null) {
                tmpRetDetail.respCode = "0";
                tmpRetDetail.respInfo = "未找到账号[" + p_req1908.singleDetail.payAct + "]商户配置信息";
                tmpRetDetail.transAmt = p_req1908.singleDetail.payAmount;
                tmpRetDetail.transState = PaymentState.FAIL_Payment;
                tmpRetDetail.payInfoCode = FailCode.E9981;
                retAts.writeRetDetail(tmpRetDetail);
                return retAts;
            }

            CITIC04Header header = new CITIC04Header();
            header.tranCode = CITIC04TransCode.deal_190802_S0001;
            header.msgno = p_req1908.singleDetail.askNumber;
            header.receiveNode = getBankConfig().getMapValueByKey("bankBranch", p_req1908.singleDetail.payAct);

            XmlTextWriter xmlWriter = new XmlTextWriter();
            xmlWriter.writeStartDocByDeclaration("<?xml version=\"1.0\" encoding=\"" + getCharset() + "\"?>");
            xmlWriter.writeStartElement("request");
            xmlWriter.writeElementString("tranCode", "S0001");
            XElement tmpXElement = new XElement("body", "");
            tmpXElement.addChild(new XElement("merchantId", actItem.merchantId));
            tmpXElement.addChild(new XElement("payChannel", ""));
            tmpXElement.addChild(new XElement("orderDate", Format.Date8Format.format(new Date())));
            tmpXElement.addChild(new XElement("orderTime", Format.Time6Format.format(new Date())));
            tmpXElement.addChild(new XElement("merSeqId", p_req1908.singleDetail.askNumber));
            String accType = "";
            if ("1".equals(p_req1908.singleDetail.isPrivate)) {
                accType = "01";
            } else {
                accType = "10";
            }
            tmpXElement.addChild(new XElement("accType", accType));//收款方账号类型(必填) 01:银行卡,02：存折,04:单位结算卡,10：单位账户
            tmpXElement.addChild(new XElement("payeeAccType", ""));
            tmpXElement.addChild(new XElement("accNo", p_req1908.singleDetail.recAct));
            tmpXElement.addChild(new XElement("accName", p_req1908.singleDetail.recName));
            tmpXElement.addChild(new XElement("payeeBankNo", getBankConfig().getMapValueByKey("recCnapsCodeMapping", p_req1908.singleDetail.recBankCode)));
            tmpXElement.addChild(new XElement("openBank", ""));
            tmpXElement.addChild(new XElement("prov", ""));
            tmpXElement.addChild(new XElement("city", ""));
            tmpXElement.addChild(new XElement("payAccNo", p_req1908.singleDetail.payAct));
            tmpXElement.addChild(new XElement("payAccName", p_req1908.singleDetail.payName));
            tmpXElement.addChild(new XElement("payerAcctType", ""));
            tmpXElement.addChild(new XElement("regionCD", ""));
            tmpXElement.addChild(new XElement("productID", ""));
            tmpXElement.addChild(new XElement("transAmt", StringHelper.amountMultiply100(p_req1908.singleDetail.payAmount)));
            tmpXElement.addChild(new XElement("purpose", p_req1908.singleDetail.purpose));
            tmpXElement.addChild(new XElement("certifTp", ""));
            tmpXElement.addChild(new XElement("certifId", ""));
            tmpXElement.addChild(new XElement("billNo", p_req1908.singleDetail.abstractATS));
            tmpXElement.addChild(new XElement("bindId", ""));
            tmpXElement.addChild(new XElement("reqReserved1", ""));
            tmpXElement.addChild(new XElement("reqReserved2", ""));
            this.nodeAnalysis(p_req1908.singleDetail.srcXElement, tmpXElement, this.getCharset());
            xmlWriter.writeXElement(tmpXElement);
            xmlWriter.writeEndDocument();

            WriteBankLogLn2("发送银行请求数据明文:\r\n" + xmlWriter.toXmlString());

            String[] tmpRetStr = sendToBank(xmlWriter.toXmlString(), header, actItem);
            if (tmpRetStr[0].length() == 0) {
                WriteBankLogStep3(tmpRetStr[1]);
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpRetStr[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpErrCode = tmpBkReader.getFirstText("/ROOT/errCode");
                    String tmpErrMsg = tmpBkReader.getFirstText("/ROOT/errMsg");
                    if (StringHelper.isNullOrEmpty(tmpErrCode)) {
                        String encrypt = tmpBkReader.getFirstText("/ROOT/encrypt");
                        String signature = tmpBkReader.getFirstText("/ROOT/signature");
                        String[] respData = decryptMessage(encrypt, signature, actItem);
                        if ("fail".equals(respData[0])) {
                            tmpRetDetail.respCode = "-1";
                            tmpRetDetail.respInfo = "验签失败！";
                            retAts.writeRetDetail(tmpRetDetail);
                            return retAts;
                        }
                        WriteBankLogLn2("解密银行返回报文:\r\n" + respData[1]);
                        XmlTextReader tmpBkReaders = loadBankRespXmlReader(respData[1], tmpSbMsg);
                        if (tmpBkReaders != null) {
                            tmpRetDetail.respCode = "0";
                            tmpRetDetail.respInfo = tmpBkReaders.getFirstText("/response/body/errMsg");
                            String tmpRespCode = tmpBkReaders.getFirstText("/response/body/errCode");
                            tmpRetDetail.transState = tmpRespCode;
                            tmpRetDetail.payInfoCode = tmpRespCode;
                        } else {
                            tmpRetDetail.respCode = "-1";
                            tmpRetDetail.respInfo = tmpSbMsg.toString();
                        }
                    } else {
                        tmpRetDetail.respCode = "-1";
                        tmpRetDetail.respInfo = tmpErrMsg;
                    }
                } else {
                    tmpRetDetail.respCode = "-1";
                    tmpRetDetail.respInfo = tmpSbMsg.toString();
                }
            } else {
                tmpRetDetail.respCode = "-1";
                tmpRetDetail.respInfo = tmpRetStr[1];
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            tmpRetDetail.respCode = "-1";
            tmpRetDetail.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }
        retAts.writeRetDetail(tmpRetDetail);
        return retAts;
    }

    public RetAtsSingleBat d_1908BAT_SglBatPay(ReqSingleBat p_req1908BAT) throws Exception {
        return null;
    }


    public RetAtsSingle d_1944_QrySglPay(ReqQrySingle p_req1944) throws Exception {
        RetAtsSingle retAts = new RetAtsSingle(p_req1944.reqHeader);
        RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail(p_req1944);
        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_req1944.payAct, "");
            if (actItem == null) {
                tmpRetDetail.respCode = "-1";
                tmpRetDetail.respInfo = "未找到账号:[" + p_req1944.payAct + "]商户配置信息!";
                retAts.writeRetDetail(tmpRetDetail);
                return retAts;
            }

            CITIC04Header header = new CITIC04Header();
            header.tranCode = CITIC04TransCode.deal_1944_S0002;
            header.msgno = p_req1944.askNumber;
            header.receiveNode = getBankConfig().getMapValueByKey("bankBranch", p_req1944.payAct);

            XmlTextWriter xmlWriter = new XmlTextWriter();
            xmlWriter.writeStartDocByDeclaration("<?xml version=\"1.0\" encoding=\"" + getCharset() + "\"?>");
            xmlWriter.writeStartElement("request");
            xmlWriter.writeElementString("tranCode", "S0002");
            xmlWriter.writeStartElement("body");
            xmlWriter.writeElementString("merchantId", actItem.merchantId);
            xmlWriter.writeElementString("orderDate", Format.Date8Format.format(new Date()));
            xmlWriter.writeElementString("orderTime", Format.Time6Format.format(new Date()));
            xmlWriter.writeElementString("merSeqId", p_req1944.askNumber);
            xmlWriter.writeElementString("orgMerSeqId", p_req1944.askNumber);
            xmlWriter.writeElementString("orgTradeDate", Format.Date8Format.format(p_req1944.getBgnDateTime()));
            xmlWriter.writeElementString("doneTranNo", "");
            xmlWriter.writeEndDocument();

            WriteBankLogLn2("发送银行请求数据明文:\r\n" + xmlWriter.toXmlString());

            String[] tmpRetStr = sendToBank(xmlWriter.toXmlString(), header, actItem);
            if (tmpRetStr[0].length() == 0) {
                WriteBankLogStep3(tmpRetStr[1]);
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpRetStr[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpErrCode = tmpBkReader.getFirstText("/ROOT/errCode");
                    String tmpErrMsg = tmpBkReader.getFirstText("/ROOT/errMsg");
                    if (StringHelper.isNullOrEmpty(tmpErrCode)) {
                        String encrypt = tmpBkReader.getFirstText("/ROOT/encrypt");
                        String signature = tmpBkReader.getFirstText("/ROOT/signature");
                        String[] respData = decryptMessage(encrypt, signature, actItem);
                        if ("fail".equals(respData[0])) {
                            tmpRetDetail.respCode = "-1";
                            tmpRetDetail.respInfo = "验签失败！";
                            retAts.writeRetDetail(tmpRetDetail);
                            return retAts;
                        }
                        WriteBankLogLn2("解密银行返回报文:\r\n" + respData[1]);
                        XmlTextReader tmpBkReaders = loadBankRespXmlReader(respData[1], tmpSbMsg);
                        if (tmpBkReaders != null) {
                            tmpRetDetail.respCode = "0";
                            tmpRetDetail.respInfo = tmpBkReaders.getFirstText("/response/body/errMsg");
                            String tmpRespCode = tmpBkReaders.getFirstText("/response/body/errCode");
                            tmpRetDetail.transState = tmpRespCode;
                            tmpRetDetail.payInfoCode = tmpRespCode;
                        } else {
                            tmpRetDetail.respCode = "-1";
                            tmpRetDetail.respInfo = tmpSbMsg.toString();
                        }
                    } else {
                        tmpRetDetail.respCode = "-1";
                        tmpRetDetail.respInfo = tmpErrMsg;
                    }
                } else {
                    tmpRetDetail.respCode = "-1";
                    tmpRetDetail.respInfo = tmpSbMsg.toString();
                }
            } else {
                tmpRetDetail.respCode = "-1";
                tmpRetDetail.respInfo = tmpRetStr[1];
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            tmpRetDetail.respCode = "-1";
            tmpRetDetail.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }
        retAts.writeRetDetail(tmpRetDetail);
        return retAts;
    }

    public RetAtsSingleBat d_1944BAT_QrySglBatPay(ReqQrySingleBat p_req1944BAT) throws Exception {
        return null;
    }
}
